package com.param_validate_demo.handler;

import com.param_validate_demo.enums.ResultCodeEnum;
import com.param_validate_demo.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Objects;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    //参数校验异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Result error(MethodArgumentNotValidException e) {
        log.warn(e.getMessage());
        Result result = Result.fail().code(ResultCodeEnum.ARGUMENT_VALID_ERROR.getCode());
        if (Objects.nonNull(e.getBindingResult().getFieldError())) {
            result.message(e.getBindingResult().getFieldError().getDefaultMessage());
        } else if (CollectionUtils.isNotEmpty(e.getBindingResult().getAllErrors())) {
            result.message(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        }
        return result;
    }

    //参数校验异常
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Result error(BindException e) {
        log.warn(e.getMessage());
        StringBuilder sb = new StringBuilder();
        for (ObjectError error : e.getBindingResult().getAllErrors()) {
            sb.append(error.getDefaultMessage());
        }
        return Result.fail()
                .code(ResultCodeEnum.ARGUMENT_VALID_ERROR.getCode())
                .message(sb.toString());
    }

    //参数校验异常
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public Result error(ConstraintViolationException e) {
        log.warn(e.getMessage());
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<?> violation : e.getConstraintViolations()) {
            sb.append(violation.getMessage());
        }
        return Result.fail()
                .code(ResultCodeEnum.ARGUMENT_VALID_ERROR.getCode())
                .message(sb.toString());
    }

    //全局异常
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result error(Exception e) {
        log.warn(e.getMessage());
        return Result.fail().message("执行了全局异常处理");
    }
}
